package org.example.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
// 安全配置
/**
 * 协作对象 : 授权服务器的端点配置
 * 作用场景 : 提供用户详情数据用于认证
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * ‌密码编码器‌
     * 通过 BCryptPasswordEncoder 对密码进行加密存储，防止明文泄露
     * @return
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder() { // 来源: org.springframework.security.crypto.bcrypt
        return new BCryptPasswordEncoder();
    }
    /**
     * 用户身份管理‌
     * 使用 UserDetailsService 实现内存用户存储，定义用户名、密码及角色
     */
    @Bean
    @Override
    public UserDetailsService userDetailsService() { // 来源: org.springframework.security.core.userdetails
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("user")
                .password("{bcrypt}$2a$10$...") // BCrypt加密密码:ml-citation{ref="4,6" data="citationList"}
                .roles("USER")
                .build());
        return manager;
    }

    /**
     * 认证管理器暴露‌
     * 将 AuthenticationManager 暴露为 Bean，供授权服务器在密码模式下使用
     * @return
     * @throws Exception
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception { // 来源: org.springframework.security.authentication
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService())
            .passwordEncoder(passwordEncoder());
    }

    /**
     * 作用‌：允许所有用户（包括未认证用户）访问 /oauth/** 路径下的接口，例如 OAuth2 的授权端点 /oauth/authorize 和令牌端点 /oauth/token8。
     * ‌适用场景‌：OAuth2 授权码模式中，客户端需通过开放端点发起授权请求，服务端需对外暴露这些接口35。
     * ‌风险提示‌：若需限制特定客户端访问，应结合 IP 白名单或动态客户端鉴权逻辑，而非完全开放
     *
     *
     * 禁用 CSRF 防护‌
     * java
     * Copy Code
     * .and()
     * .csrf().disable();
     * ‌作用‌：关闭跨站请求伪造（CSRF）防护机制，避免因 CSRF Token 校验导致的接口拒绝访问问题37。
     * ‌适用场景‌：
     * 纯 API 服务（如 RESTful 接口），使用 Token 或 OAuth2 认证时无需 CSRF 防护37。
     * 简化调试流程（如 Postman 测试）时临时关闭7。
     * ‌风险提示‌：若为传统 Web 应用（含表单提交），禁用 CSRF 可能导致安全漏洞，需谨慎操作
     * @param http
     * @throws Exception
     */
    public void configure(HttpSecurity http) throws Exception{
//        http
//                .authorizeRequests()
//                .antMatchers("/oauth/**").permitAll()  // 开放OAuth2端点:ml-citation{ref="8" data="citationList"}
//                .and()
//                .csrf().disable();
        http
                .authorizeRequests()
                .antMatchers("/oauth/**").authenticated()  // 必须认证
                .and()
                .csrf().disable()
                .formLogin()  // 启用表单登录
//                .loginPage("/login")  // 自定义登录页（可选）
                .permitAll();
    }
}
